/******************************************************************************
 * * qq_data.c
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/

#include "qq_data_interface.h"
#include "lv_watch.h"

#define QQ_LOGIN_FILE   "C:/qq_login"
#define QQ_LOGIN_MAX_CNT  1
#define QQ_FRIEND_PATHNAME_MAX_LEN  20

static char qqid_own[QQ_ID_LEN];

void watch_qq_save_login_info(watch_qq_login_info_t * info)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint32_t bw = 0;
    uint8_t login_cnt = 0;
    uint8_t login_oldest_index = 0;
    uint32_t login_oldest_time = 0;
    uint8_t i = 0;
    watch_qq_login_info_t login_info_all[QQ_LOGIN_MAX_CNT];

    if(NULL == info) {
        return;
    }

    memset(login_info_all, 0, sizeof(watch_qq_login_info_t) * QQ_LOGIN_MAX_CNT);
    memset(qqid_own, 0, QQ_ID_LEN);
    printf("%s: qqid = %s\n", __FUNCTION__, info->qqid);
    strncpy(qqid_own, info->qqid, strlen(info->qqid));

    res = lv_fs_open(&file, QQ_LOGIN_FILE, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        login_cnt = file_size / sizeof(watch_qq_login_info_t);
        if(login_cnt > QQ_LOGIN_MAX_CNT) {
            login_cnt = QQ_LOGIN_MAX_CNT;
        }
        lv_fs_read(&file, login_info_all, login_cnt * sizeof(watch_qq_login_info_t), &br);
        lv_fs_close(&file);

        for(i = 0; i < login_cnt; i++) {  //update if qqid found
            if(0 == strcmp(login_info_all[i].qqid, info->qqid)) {
                memcpy(login_info_all + i, info, sizeof(watch_qq_login_info_t));
                break;
            }
        }

        if(i == login_cnt) {
            if(QQ_LOGIN_MAX_CNT == login_cnt) {  //replace oldest
                for(i = 0; i < login_cnt; i++) {
                    if((0 == login_oldest_time) || (login_info_all[i].login_time < login_oldest_time)) {
                        login_oldest_time = login_info_all[i].login_time;
                        login_oldest_index = i;
                    }
                }

                printf("%s: remove own head path = %s\n", __FUNCTION__, login_info_all[login_oldest_index].head_path);
                lv_fs_remove(login_info_all[login_oldest_index].head_path);

                char friend_file[QQ_FRIEND_PATHNAME_MAX_LEN];
                memset(friend_file, 0, QQ_FRIEND_PATHNAME_MAX_LEN);
                snprintf(friend_file, QQ_FRIEND_PATHNAME_MAX_LEN, "C:/qq_%s", login_info_all[login_oldest_index].qqid);
                res = lv_fs_open(&file, friend_file, LV_FS_MODE_RD);
                if(res == LV_FS_RES_OK) {
                    lv_fs_size(&file, &file_size);
                    uint32_t friend_cnt = file_size / sizeof(watch_qq_friend_info_t);
                    watch_qq_friend_info_t * friend_list = lv_mem_alloc(file_size + 1);
                    memset(friend_list, 0, file_size + 1);
                    lv_fs_read(&file, friend_list, file_size, &br);
                    lv_fs_close(&file);

                    for(uint32_t j = 0; j < friend_cnt; j++) {
                        printf("%s: remove friends' head path = %s\n", __FUNCTION__, friend_list[j].headpath);
                        lv_fs_remove(friend_list[j].headpath);
                    }
                    lv_mem_free(friend_list);

                    printf("%s: remove friend file = %s\n", __FUNCTION__, friend_file);
                    lv_fs_remove(friend_file);
                }

                memcpy(login_info_all + login_oldest_index, info, sizeof(watch_qq_login_info_t));
            } else {  //append
                memcpy(login_info_all + login_cnt, info, sizeof(watch_qq_login_info_t));
                login_cnt ++;
            }
        }

        lv_fs_open(&file, QQ_LOGIN_FILE, LV_FS_MODE_RD | LV_FS_MODE_APPEND);
        lv_fs_seek(&file, 0);
        lv_fs_write(&file, login_info_all, login_cnt * sizeof(watch_qq_login_info_t), &bw);
        lv_fs_close(&file);

    } else {
        res = lv_fs_open(&file, QQ_LOGIN_FILE, LV_FS_MODE_WR);
        if(res == LV_FS_RES_OK) {
            lv_fs_close(&file);
        } else {
            printf("%s: create login file failed\n", __FUNCTION__);
            return;
        }

        lv_fs_open(&file, QQ_LOGIN_FILE, LV_FS_MODE_RD | LV_FS_MODE_APPEND);
        lv_fs_seek(&file, 0);
        lv_fs_write(&file, info, sizeof(watch_qq_login_info_t), &bw);
        lv_fs_close(&file);
    }
}

void watch_qq_save_my_head_path(char * qqid, char * path)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint32_t bw = 0;
    uint8_t login_cnt = 0;
    uint8_t i = 0;
    watch_qq_login_info_t login_info_all[QQ_LOGIN_MAX_CNT];

    if(NULL == path) {
        return;
    }

    res = lv_fs_open(&file, QQ_LOGIN_FILE, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        login_cnt = file_size / sizeof(watch_qq_login_info_t);
        if(login_cnt > QQ_LOGIN_MAX_CNT) {
            login_cnt = QQ_LOGIN_MAX_CNT;
        }
        lv_fs_read(&file, login_info_all, login_cnt * sizeof(watch_qq_login_info_t), &br);
        lv_fs_close(&file);

        for(i = 0; i < login_cnt; i++) {
            if(0 == strcmp(login_info_all[i].qqid, qqid)) {
                memcpy(login_info_all[i].head_path, path, QQ_HEAD_PATH_LEN);
                break;
            }
        }

        if(i == login_cnt) {
            printf("%s: cannot find qqid\n", __FUNCTION__);
            return;
        }
        printf("%s: update login_info[%d]\n", __FUNCTION__, i);
        lv_fs_open(&file, QQ_LOGIN_FILE, LV_FS_MODE_RD | LV_FS_MODE_APPEND);
        lv_fs_seek(&file, 0);
        lv_fs_write(&file, &login_info_all[i], sizeof(watch_qq_login_info_t), &bw);
        lv_fs_close(&file);
    }
}


watch_qq_login_info_t * watch_qq_get_last_login_info(void)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint8_t login_cnt = 0;
    uint8_t login_recent_index = 0;
    uint32_t login_recent_time = 0;
    uint8_t i = 0;
    watch_qq_login_info_t login_info_all[QQ_LOGIN_MAX_CNT];
    watch_qq_login_info_t * login_info = NULL;

    memset(login_info_all, 0, sizeof(watch_qq_login_info_t) * QQ_LOGIN_MAX_CNT);
    memset(qqid_own, 0, QQ_ID_LEN);

    res = lv_fs_open(&file, QQ_LOGIN_FILE, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        login_cnt = file_size / sizeof(watch_qq_login_info_t);
        if(login_cnt > QQ_LOGIN_MAX_CNT) {
            login_cnt = QQ_LOGIN_MAX_CNT;
        }
        lv_fs_read(&file, login_info_all, login_cnt * sizeof(watch_qq_login_info_t), &br);
        lv_fs_close(&file);

        if(login_cnt > 0) {
            for(i = 0; i < login_cnt; i++) {  //get recent
                if((login_info_all[i].login_time > login_recent_time)) {
                    login_recent_time = login_info_all[i].login_time;
                    login_recent_index = i;
                }
            }

            login_info = lv_mem_alloc(sizeof(watch_qq_login_info_t));
            memcpy(login_info, login_info_all + login_recent_index, sizeof(watch_qq_login_info_t));
            strncpy(qqid_own, login_info->qqid, QQ_ID_LEN);
        }
    }

    return login_info;
}

void watch_qq_add_friend(watch_qq_friend_info_t * info)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint32_t bw = 0;
    uint32_t friend_cnt = 0;
    uint32_t i = 0;
    char pathfile[QQ_FRIEND_PATHNAME_MAX_LEN];
    watch_qq_friend_info_t * friend_list = NULL;

    if(0 == strlen(qqid_own)) {
        printf("%s: no qqid_own\n", __FUNCTION__);
        return;
    }

    if(NULL == info) {
        return;
    }

    printf("%s: qqid:%s, path:%s\n", __FUNCTION__, info->qqid, info->headpath);
    memset(pathfile, 0, QQ_FRIEND_PATHNAME_MAX_LEN);
    snprintf(pathfile, QQ_FRIEND_PATHNAME_MAX_LEN, "C:/qq_%s", qqid_own);
    printf("%s: pathfile = %s\n", __FUNCTION__, pathfile);
    res = lv_fs_open(&file, pathfile, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        friend_cnt = file_size / sizeof(watch_qq_friend_info_t);
        friend_list = lv_mem_alloc(file_size + 1);
        memset(friend_list, 0, file_size + 1);
        lv_fs_read(&file, friend_list, file_size, &br);
        lv_fs_close(&file);

        lv_fs_open(&file, pathfile, LV_FS_MODE_RD | LV_FS_MODE_APPEND);

        for(i = 0; i < friend_cnt; i++) {  //update if qqid found
            if(0 == strncmp(friend_list[i].qqid, info->qqid, strlen(info->qqid))) {
                lv_fs_seek(&file, i * sizeof(watch_qq_friend_info_t));
                break;
            }
        }

        if(i == friend_cnt) {
            for(i = 0; i < friend_cnt; i++) {  //find first empty position
                if(0 == strlen(friend_list[i].qqid)) {
                    lv_fs_seek(&file, i * sizeof(watch_qq_friend_info_t));
                    break;
                }
            }

            if(i == friend_cnt) {  //append
                lv_fs_close(&file);
                lv_fs_open(&file, pathfile, LV_FS_MODE_WR | LV_FS_MODE_APPEND);
            }
        }

        lv_fs_write(&file, info, sizeof(watch_qq_friend_info_t), &bw);
        lv_fs_close(&file);
        lv_mem_free(friend_list);

    } else {
        res = lv_fs_open(&file, pathfile, LV_FS_MODE_WR);
        if(res == LV_FS_RES_OK) {
            lv_fs_close(&file);
        } else {
            printf("%s: create %s failed\n", __FUNCTION__, pathfile);
            return;
        }

        lv_fs_open(&file, pathfile, LV_FS_MODE_RD | LV_FS_MODE_APPEND);
        lv_fs_seek(&file, 0);
        lv_fs_write(&file, info, sizeof(watch_qq_friend_info_t), &bw);
        lv_fs_close(&file);
    }
}

void watch_qq_del_friend(char * qqid_friend)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint32_t bw = 0;
    uint32_t friend_cnt = 0;
    uint32_t i = 0;
    char pathfile[QQ_FRIEND_PATHNAME_MAX_LEN];
    watch_qq_friend_info_t * friend_list = NULL;
    watch_qq_friend_info_t friend_empty;

    if(0 == strlen(qqid_own)) {
        printf("%s: no qqid_own\n", __FUNCTION__);
        return;
    }

    printf("%s: qqid_friend = %s\n", __FUNCTION__, qqid_friend);
    memset(&friend_empty, 0, sizeof(watch_qq_friend_info_t));
    memset(pathfile, 0, QQ_FRIEND_PATHNAME_MAX_LEN);
    snprintf(pathfile, QQ_FRIEND_PATHNAME_MAX_LEN, "C:/qq_%s", qqid_own);

    res = lv_fs_open(&file, pathfile, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        friend_cnt = file_size / sizeof(watch_qq_friend_info_t);
        friend_list = lv_mem_alloc(file_size + 1);
        memset(friend_list, 0, file_size + 1);
        lv_fs_read(&file, friend_list, file_size, &br);
        lv_fs_close(&file);

        lv_fs_open(&file, pathfile, LV_FS_MODE_RD | LV_FS_MODE_APPEND);

        for(i = 0; i < friend_cnt; i++) {  //delete if qqid found
            if(0 == strncmp(friend_list[i].qqid, qqid_friend, strlen(qqid_friend))) {
                printf("%s: remove headpath = %s\n", __FUNCTION__, friend_list[i].headpath);
                lv_fs_remove(friend_list[i].headpath);
                lv_fs_seek(&file, i * sizeof(watch_qq_friend_info_t));
                lv_fs_write(&file, &friend_empty, sizeof(watch_qq_friend_info_t), &bw);
                break;
            }
        }

        lv_fs_close(&file);
        lv_mem_free(friend_list);
    }
}

char * watch_qq_get_friend_head_path(char * openid_friend)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint32_t friend_cnt = 0;
    uint32_t i = 0;
    char pathfile[QQ_FRIEND_PATHNAME_MAX_LEN];
    watch_qq_friend_info_t * friend_list = NULL;
    char * head_path = NULL;

    if(0 == strlen(qqid_own)) {
        printf("%s: no qqid_own\n", __FUNCTION__);
        return NULL;
    }

    memset(pathfile, 0, QQ_FRIEND_PATHNAME_MAX_LEN);
    snprintf(pathfile, QQ_FRIEND_PATHNAME_MAX_LEN, "C:/qq_%s", qqid_own);

    res = lv_fs_open(&file, pathfile, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        friend_cnt = file_size / sizeof(watch_qq_friend_info_t);
        friend_list = lv_mem_alloc(file_size + 1);
        memset(friend_list, 0, file_size + 1);
        lv_fs_read(&file, friend_list, file_size, &br);
        lv_fs_close(&file);

        printf("%s:friend_cnt = %d\n", __FUNCTION__, friend_cnt);
        for(i = 0; i < friend_cnt; i++) {
            if(0 == strncmp(friend_list[i].openid, openid_friend, strlen(openid_friend))) {
                head_path = lv_strdup(friend_list[i].headpath);
                break;
            }
        }
        lv_mem_free(friend_list);
    }
    printf("%s: head_path = %s\n", __FUNCTION__, head_path);
    return head_path;
}

void watch_qq_update_friend_seq_id(char * qqid_friend, uint16_t seq_id)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint32_t bw = 0;
    uint32_t friend_cnt = 0;
    uint32_t i = 0;
    char pathfile[QQ_FRIEND_PATHNAME_MAX_LEN];
    watch_qq_friend_info_t * friend_list = NULL;

    if(0 == strlen(qqid_own)) {
        printf("%s: no qqid_own\n", __FUNCTION__);
        return;
    }

    memset(pathfile, 0, QQ_FRIEND_PATHNAME_MAX_LEN);
    snprintf(pathfile, QQ_FRIEND_PATHNAME_MAX_LEN, "C:/qq_%s", qqid_own);

    res = lv_fs_open(&file, pathfile, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        friend_cnt = file_size / sizeof(watch_qq_friend_info_t);
        friend_list = lv_mem_alloc(file_size);
        lv_fs_read(&file, friend_list, file_size, &br);
        lv_fs_close(&file);

        lv_fs_open(&file, pathfile, LV_FS_MODE_RD | LV_FS_MODE_APPEND);

        for(i = 0; i < friend_cnt; i++) {  //update if qqid found
            if(0 == strcmp(friend_list[i].qqid, qqid_friend)) {
                lv_fs_seek(&file, i * sizeof(watch_qq_friend_info_t) + QQ_ID_LEN + 64 + QQ_HEAD_PATH_LEN);
                lv_fs_write(&file, &seq_id, sizeof(uint16_t), &bw);
                break;
            }
        }

        lv_fs_close(&file);
        lv_mem_free(friend_list);
    }
}

extern uint16_t watch_qq_get_friend_seq_id(char * qqid_friend)
{
    lv_fs_res_t res;
    lv_fs_file_t file;
    uint32_t file_size = 0;
    uint32_t br = 0;
    uint32_t bw = 0;
    uint32_t friend_cnt = 0;
    uint32_t i = 0;
    char pathfile[QQ_FRIEND_PATHNAME_MAX_LEN];
    watch_qq_friend_info_t * friend_list = NULL;
    uint16_t seq_id = 0;

    if(0 == strlen(qqid_own)) {
        printf("%s: no qqid_own\n", __FUNCTION__);
        return 0;
    }

    memset(pathfile, 0, QQ_FRIEND_PATHNAME_MAX_LEN);
    snprintf(pathfile, QQ_FRIEND_PATHNAME_MAX_LEN, "C:/qq_%s", qqid_own);

    res = lv_fs_open(&file, pathfile, LV_FS_MODE_RD);
    if(res == LV_FS_RES_OK) {
        lv_fs_size(&file, &file_size);
        friend_cnt = file_size / sizeof(watch_qq_friend_info_t);
        friend_list = lv_mem_alloc(file_size);
        lv_fs_read(&file, friend_list, file_size, &br);
        lv_fs_close(&file);

        for(i = 0; i < friend_cnt; i++) {
            if(0 == strcmp(friend_list[i].qqid, qqid_friend)) {
                seq_id = friend_list[i].msg_seq_id;
                break;
            }
        }
        lv_mem_free(friend_list);
        if(i == friend_cnt) {  //not find
            printf("%s: add new_friend info\n", __FUNCTION__);
            lv_fs_open(&file, pathfile, LV_FS_MODE_WR | LV_FS_MODE_APPEND);
            watch_qq_friend_info_t info;
            memset(&info, 0, sizeof(watch_qq_friend_info_t));
            strncpy(info.qqid, qqid_friend, 64);
            info.msg_seq_id = 0;
            lv_fs_write(&file, &info, sizeof(watch_qq_friend_info_t), &bw);
            lv_fs_close(&file);

        }
    }

    return seq_id;
}

